﻿using System;

namespace Infrastructure.Data.Validation
{
    /// <summary>
    /// 数据验证注册类
    /// </summary>
    public static class ValidatorRegistry
    {
        #region Members
        private static readonly DictionaryByType SaveValidators = new DictionaryByType();
        private static readonly DictionaryByType DeleteValidators = new DictionaryByType();
        private static readonly DictionaryByType ConcurrencyValidators = new DictionaryByType();
        private static readonly DictionaryByType DbErrorHandlers = new DictionaryByType();
        #endregion

        #region Methods
        /// <summary>
        /// 注册保存数据验证
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="validator"></param>
        /// <example>
        /// 
        /// </example>
        public static void RegisterSaveValidator<T>(SpecificationValidator<T> validator) where T : class
        {
            SaveValidators.Add<SpecificationValidator<T>>(validator);
        }

        /// <summary>
        /// 注册删除数据验证
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="validator"></param>
        public static void RegisterDeleteValidator<T>(SpecificationValidator<T> validator) where T : class
        {
            DeleteValidators.Add<SpecificationValidator<T>>(validator);
        }

        /// <summary>
        /// 注册删除数据验证
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="validationFunction"></param>
        /// <param name="modelName"></param>
        /// <param name="entityName"></param>
        public static void RegisterDeleteValidator<T>(Func<T, bool> validationFunction, string modelName, string entityName) where T : class
        {
            SpecificationValidator<T> validator = new GenericDeleteValidator<T>(validationFunction, modelName, entityName);
            DeleteValidators.Add(validator);
        }

        /// <summary>
        /// 注册数据库错误验证
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="validator"></param>
        public static void RegisterDbErrorHandler<T>(SpecificationValidator<T> validator) where T : class
        {
            DbErrorHandlers.Add(validator);
        }
       
        /// <summary>
        /// 注册并发数据验证
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="validator"></param>
        public static void RegisterConcurrencyValidator<T>(ConcurrencyValidator<T> validator) where T : class
        {
            ConcurrencyValidators.Add(validator);
        }

        /// <summary>
        /// 获取保存数据验证错误消息
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="model"></param>
        /// <returns></returns>
        public static string GetSaveErrorMessage<T>(T model) where T : class
        {
            SpecificationValidator<T> specificationValidator;
            ValidatorRegistry.SaveValidators.TryGet<SpecificationValidator<T>>(out specificationValidator);
            if (specificationValidator == null)
            {
                return "";
            }
            return specificationValidator.GetErrorMessage(model);
        }

        /// <summary>
        /// 获取删除数据验证错误消息
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="model"></param>
        /// <returns></returns>
        public static string GetDeleteErrorMessage<T>(T model) where T : class
        {
            SpecificationValidator<T> specificationValidator;
            ValidatorRegistry.DeleteValidators.TryGet<SpecificationValidator<T>>(out specificationValidator);
            if (specificationValidator == null)
            {
                return "";
            }
            return specificationValidator.GetErrorMessage(model);
        }

        /// <summary>
        /// 获取并发数据验证错误消息
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="current"></param>
        /// <param name="loaded"></param>
        /// <returns></returns>
        public static ConcurrencyCheckResult GetConcurrencyErrorMessage<T>(T current, T loaded) where T : class
        {
            ConcurrencyValidator<T> concurrencyValidator;
            ValidatorRegistry.ConcurrencyValidators.TryGet<ConcurrencyValidator<T>>(out concurrencyValidator);
            if (concurrencyValidator == null)
            {
                return ConcurrencyCheckResult.Continue();
            }
            return concurrencyValidator.GetErrorMessage(current, loaded);
        }

        /// <summary>
        /// 获取数据库数据验证错误消息
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="model"></param>
        /// <returns></returns>
        public static string GetDbErrorHandlingMessage<T>(T model) where T : class
        {
            SpecificationValidator<T> specificationValidator;
            ValidatorRegistry.DbErrorHandlers.TryGet<SpecificationValidator<T>>(out specificationValidator);
            if (specificationValidator == null)
            {
                return "";
            }
            return specificationValidator.GetErrorMessage(model);
        }
        #endregion
    }
}
